package bishi;

import java.time.LocalDate;
import java.util.*;

/**
 * @author: 唐小尊
 * @email: 1171702529@qq.com
 * @cate: 2021/05/10 09:00
 */
public class TradingDayServiceImpl implements TradingDayService {

    static Map<Integer, Node> cache = new HashMap<>();

    //初始化缓存
    static {
        //1、存入所有非周末
        int year = 2020;
        Node node = new Node();
        LocalDate of = LocalDate.of(year, 1, 1);
        while (of.getYear() == year) {
            node.set(of);
            of = of.plusDays(1);
        }

        //2、添加year=2020的节日
        List<Festival> festivals = new ArrayList<>();
        //节日名，日期，放假时间
        festivals.add(new Festival("国庆", LocalDate.of(year, 10, 1), 8));

        //3、删除所有的节日放假日期
        //foreach会创造一个iterator对象，一直next，导致list的随机访问起不到作用，速度变慢
        for (int i = 0; i < festivals.size(); i++) {
            cache.get(2020).removeMany(festivals.get(i).date, festivals.get(i).num);
        }
    }


    @Override
    public boolean isTradingDay(LocalDate date) {
        return cache.get(date.getYear()).isExist(date);
    }

    @Override
    public Optional<LocalDate> queryNextTradingDay(LocalDate date) {
        LocalDate res = cache.get(date.getYear()).getNext(date);
        if (res == null) {
            //1月1日必定不是工作日！
            res = cache.get(date.getYear() + 1).getNext(LocalDate.of(date.getYear() + 1, 1, 1));
        }
        return Optional.of(res);
    }

    @Override
    public List<LocalDate> queryBetween(LocalDate from, LocalDate to) {
        if (from.compareTo(to) > 0) {
            System.out.println("开始时间不能大于结束时间");
            return null;
        }
        List<LocalDate> res;
        if (to.getYear() != from.getYear()) {
            res = cache.get(from.getYear()).queryBetween(from, LocalDate.of(from.getYear(), 12, 31));
            int nowYear = from.getYear() + 1;
            while (nowYear < to.getYear()) {
                res.addAll(cache.get(nowYear).queryBetween(LocalDate.of(nowYear, 1, 1), LocalDate.of(nowYear, 12, 31)));
                nowYear++;
            }
            res.addAll(cache.get(nowYear).queryBetween(LocalDate.of(nowYear, 1, 1), to));
        } else {
            return cache.get(from.getYear()).queryBetween(from, to);
        }
        return res;
    }

    @Override
    public Optional<LocalDate> queryFirstTradingDayOfMonth(LocalDate date) {
        LocalDate of = LocalDate.of(date.getYear(), date.getMonth(), 1);
        if (cache.get(date.getYear()).isExist(of)) {
            return Optional.of(of);
        }
        return queryNextTradingDay(date);
    }
}
